import { getValue, getEnvAttr } from "../../util/ObjectUtil.js";
import { generateCode, isTrue } from "../../util/code.js";

export function checkVBind(vm, vnode) {
  // vbind语法分析
  if (vnode.nodeType !== 1) {
    return false;
  }
  let attrNames = vnode.elm.getAttributeNames();
  let len = attrNames.length;
  for (let i = 0; i < len; i++) {
    if (
      attrNames[i].indexOf("v-bind:") === 0 ||
      attrNames[i].indexOf(":") === 0
    ) {
      vBind(vm, vnode, attrNames[i], vnode.elm.getAttribute(attrNames[i]));
    }
  }
}
function vBind(vm, vnode, name, value) {
  // name属性名，value属性值
  let k = name.split(":")[1];
  if (/^{[\w\W]+}$/.test(value)) {
    // 处理v-bind语句中有花括号的语法(比如v-bind:class="{red: obj.x < 2}")
    let str = value.substring(1, value.length - 1).trim(); // 如果有括号就去括号
    let expressionList = str.split(","); // 把多个指令拆分成指令集
    let result = analysisExpression(vm, vnode, expressionList);
    vnode.elm.setAttribute(k, result);
  } else {
    // v-bind的常规写法(不带表达式的写法)
    let v = getValue(vm._data, value);
    vnode.elm.setAttribute(k, v);
  }
}
function analysisExpression(vm, vnode, expressionList) {
  // 解析指令
  // 获取当前环境的变量
  // debugger
  let attr = getEnvAttr(vm, vnode);
  // 判断表达式是否成立
  // debugger
  let envCode = generateCode(attr); // 生成执行环境下的代码
  // 拼租result
  let result = "";
  for (let i = 0; i < expressionList.length; i++) {
    let site = expressionList[i].indexOf(":");
    if (site > -1) {
      // 处理含有冒号的表达式(形如{red: obj.x < 2})
      let code = expressionList[i].substring(
        site + 1,
        expressionList[i].length
      );
      // 接取冒号后的内容(获得“obj.x < 2”语句)
      // 结合上面的环境声明代码，来验证这个表达式是否成立
      if (isTrue(code, envCode)) {
        // expressionList[i].substring(0, site)获取的是冒号前的内容(形如red)
        result += expressionList[i].substring(0, site) + ",";
      }
    } else {
      // 处理没有冒号的形式(形如{red})
      result += expressionList[i] + ",";
    }
  }
  if (result.length > 0) {
    // 去掉最后一项后的逗号
    result = result.substring(0, result.length - 1);
  }
  return result;
}
